package com.fc.test.util;

import java.util.*;

/**
 * describe: 中奖概率设置
 *
 * @author xugang
 * @date 2018/9/20 10:33
 */
public class ProbabilityUtils {
    private static int total = 100; //中奖率百分比

    /**
     * 八种概率值枚举 (八种概率值，随着概率值越大，中奖难度也越大)
     */
    private enum EPROBABILITY {
        ZERO(0, 1), // ZERO默认值为1，请勿修改
        ONE(1, 10),
        TWO(2, 9),
        THREE(3, 8),
        FOUR(4, 7),
        FIVE(5, 6),
        SIX(6, 5),
        SEVEN(7, 4);

        // 概率值
        private int probability;

        //出现的频次
        private int frequency;

        private EPROBABILITY(int probability, int frequency) {
            this.probability = probability;
            this.frequency = frequency;
        }

        public int getProbability() {
            return probability;
        }

        public int getFrequency() {
            return frequency;
        }
    }

    private static int tempProbability = 0; // 下一次要获取的概率值

    private static List<Integer> pastProbabilitys = new ArrayList<Integer>(); // 已使用的概率值集合

    private static List<Integer> probabilitys = new ArrayList<Integer>();     // 初始的概率值集合

    /*
     * 初始化各概率数据到 probabilitys 集合中
     */
    static {
        // 概率计算
        List<Map<Integer, Integer>> maps = new ArrayList<Map<Integer, Integer>>();
        EPROBABILITY[] eprobabilities = EPROBABILITY.values();
        for (EPROBABILITY eprobability : eprobabilities) {
            int x = eprobability.getProbability();
            int y = eprobability.getFrequency();
            int z = total / y;
            for (int i = 1; i <= y; i++) {
                Map<Integer, Integer> map = new HashMap<Integer, Integer>();
                map.put(x, i * z);
                maps.add(map);
            }
        }

        // 初始化概率值集合 probabilitys
        for (int i = 1; i <= total; i++) {
            boolean is_zero = true;
            step:
            for (Map<Integer, Integer> map : maps) {
                for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
                    int key = entry.getKey();
                    if (key == 0) {
                        continue;
                    }
                    int value = entry.getValue();
                    if (i == value) {
                        probabilitys.add(key);
                        is_zero = false;
                        break step;
                    }
                }
            }
            // 没有找到符合的概率值，设默认值
            if (is_zero) {
                probabilitys.add(EPROBABILITY.ZERO.getProbability());
            }
        }
    }

    /**
     * 获取概率值
     *
     * @return 0-7 之间八种概率值
     */
    public synchronized static int generateProbability() {
        int probability = tempProbability;
        Iterator<Integer> iterator = probabilitys.iterator();
        if (iterator.hasNext()) {
            tempProbability = iterator.next();
            iterator.remove();
            pastProbabilitys.add(tempProbability);
        } else {
            return generateProbability(pastProbabilitys, probabilitys);
        }
        return probability;
    }

    /**
     * 重置概率值集合中的内容
     *
     * @param pastProbabilitys 已使用的概率值集合
     * @param probabilitys     初始的概率值集合
     * @return
     */
    private static int generateProbability(List<Integer> pastProbabilitys, List<Integer> probabilitys) {
        System.out.println("===>>>  已完成100人抽奖， 重置概率值集合中的内容！<<<===");
        Iterator<Integer> iterator = pastProbabilitys.iterator();
        while (iterator.hasNext()) {
            probabilitys.add(iterator.next());
            iterator.remove();
        }
        return generateProbability();
    }

   /* public static void main(String[] args) {
        int size = probabilitys.size();

        System.out.println("==================== 从集合中直接获取概率值： ==================== ");
        System.out.println("probabilitys.size = [" + size + "]");
        for (int i = 0; i < size; i++) {
            System.out.println("number : [" + (i + 1) + "] ------>>> 概率值 ： " + probabilitys.get(i));
        }
        System.out.println("probabilitys.size = [" + probabilitys.size() + "]");
        System.out.println("pastProbabilitys.size = [" + pastProbabilitys.size() + "]");


        System.out.println("==================== 循环调用方法获取概率值： ====================");
        for (int i = 0; i < size; i++) {
            System.out.println("number : [" + (i + 1) + "] ------>>> 概率值 ： " + generateProbability());
        }
        System.out.println("==================== 获取概率值之后： ====================");
        System.out.println("probabilitys.size = [" + probabilitys.size() + "]");
        System.out.println("pastProbabilitys.size = [" + pastProbabilitys.size() + "]");


        System.out.println("==================== 单独调用方法获取概率值： ====================");
        System.out.println("number : [" + 1 + "] ------>>> 概率值 ： " + generateProbability());
        System.out.println("==================== 获取概率值之后： ====================");
        System.out.println("probabilitys.size = [" + probabilitys.size() + "]");
        System.out.println("pastProbabilitys.size = [" + pastProbabilitys.size() + "]");
    }*/
}
